package com.p2p.web.controller;


import java.text.ParseException;
import java.util.Date;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;

import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.Errors;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;

import com.p2p.base.cache.Cache;
import com.p2p.base.global.DomainConst;
import com.p2p.base.model.BaseUser;
import com.p2p.base.model.LoginCount;
import com.p2p.base.model.LoginLog;
import com.p2p.base.service.LoginCountService;
import com.p2p.base.service.LoginLogService;
import com.p2p.base.service.UserService;
import com.p2p.base.util.AES;
import com.p2p.base.util.BasePropertyConfigurer;
import com.p2p.base.util.Const;
import com.p2p.base.util.CookieWrapper;
import com.p2p.base.util.DateUtil;
import com.p2p.base.util.Encrypter;
import com.p2p.base.util.LoginToken;
import com.p2p.base.util.LoginUtil;
import com.p2p.base.util.MD5Util;
import com.p2p.base.web.controller.BaseController;
import com.p2p.web.form.LoginForm;

/**
 * @author ruiqi
 *
 */
@Controller
public class LoginController extends BaseController{
	
	private static final String YQH_UT = "yqh_ut";

	@Resource
	private Cache loginCache;
	
	@Resource
	private LoginLogService loginLogService;
	
	@Resource
	private LoginCountService loginCountService;
	
	

	@Resource
	private UserService userService;

	
	@RequestMapping(value="/login")
	public String login(String backUrl,Model model,HttpServletRequest request,HttpServletResponse response) throws Exception{
		model.addAttribute("backUrl", backUrl);
		LoginForm loginForm = new LoginForm();
		model.addAttribute("loginForm", loginForm);
		return "login/login";
	}
	
	@RequestMapping(value="/checklogin")
	public String checklogin(String backUrl,@Valid LoginForm loginForm,Errors errors, HttpServletRequest request,HttpServletResponse response) throws Exception{
		if(errors.hasErrors()){
			return "login/login";
		}
		LoginUtil.setCurrentUser(null);
		checkPwd(loginForm.getLoginName(),loginForm.getLoginPswd(),errors);
		if(errors.hasErrors()){
			return "login/login";
		}
		BaseUser user = (BaseUser)LoginUtil.getCurrentUser();
		LoginUtil.setCurrentUser(null);
		if(user!=null){			
			loginLogAndCountBeforeCookie(request, user);
			loginCookieAndCacheUser(user, response);
			if(StringUtils.isBlank(backUrl)){
				backUrl = BasePropertyConfigurer.getContextProperty("p2p.login_back_url");
			}
			return "redirect:"+backUrl;
		}
		return "login/login";
	}

	private void loginLogAndCountBeforeCookie(HttpServletRequest request, BaseUser user) {
		LoginCount loginCount = loginCountService.getByUid(user.getId());
		if(loginCount==null){
			loginCount = new LoginCount();
			loginCount.setUid(user.getId());
			loginCount.setTimes(0);
			loginCount.setWrongTimes(0);
			loginCountService.create(loginCount);			
		}			
		user.setLastLoginIp(loginCount.getLastLoginIp());
		user.setLastLogintype(loginCount.getLastLoginType());
		user.setLastLoginTime(loginCount.getLastLoginTime());
		user.setLoginTimes(loginCount.getTimes()+1);
		String ip = LoginUtil.getRemoteIp(request); 
		loginLogService.create(user.getId(),ip,LoginLog.TypeEnum.web_login);
		loginCount.setLastLoginIp(ip);
		loginCount.setLastLoginType(LoginLog.TypeEnum.web_login.name());
		//更新本次登录信息
		loginCountService.updateSuccessTimes(loginCount);
	}
	
	private void loginCookieAndCacheUser(BaseUser user,HttpServletResponse response) throws Exception{
		String key = AES.Encrypt(user.getId(), Const.KEY);
		String p2pDomainName = p2pDomianName();
		CookieWrapper.setCookie(response, YQH_UT, key, p2pDomainName, -1);
		loginCache.add(key, user, 3*60);
	}

	private String p2pDomianName() {
		String p2pDomainName = BasePropertyConfigurer.getContextProperty("p2p.domain");
		return p2pDomainName;
	}
	
	//注册之后，带token标志位跳转到这里，解析token为3部分，校验通过，设置cookie，最后跳转到个人主页
	@RequestMapping(value="/tokenlogin")
	public String tokenLogin(@RequestParam String token, @RequestParam String backUrl,HttpServletRequest request,HttpServletResponse response) throws Exception{
		if(StringUtils.isNotEmpty(token) || StringUtils.isNotEmpty(backUrl)){
			String decryptToken=Encrypter.decrypt(token);
			//0-uname,1-salt,2-date
			String[] tokenArray = decryptToken.split(",");
			//Token标志位必须一致
			boolean tokenSame = tokenArray[1].equals(LoginToken.DEFAULT_SALT);
			//注册当天
			boolean dateSame=false;
			try {
				Date tokenDate=DateUtil.parseStandardDate(tokenArray[2]);
				dateSame=DateUtil.isSameDay(tokenDate, new Date());
			} catch (ParseException e) {
				e.printStackTrace();
			}
			if(tokenSame && dateSame){
				BaseUser user = userService.findByLoginName(tokenArray[0]);
				loginLogAndCountBeforeCookie(request, user);
				loginCookieAndCacheUser(user, response);
				return "redirect:"+backUrl;
			}
		}
		
		return "login/login";
	}
	
	
	private void checkPwd(String loginName,String pwStr,Errors errors){
		BaseUser user = userService.findByLoginName(loginName);
		String errorTip = "用户名或密码不正确";
		if(user==null){		
			errors.rejectValue("loginName","no_exist" , errorTip);
			return;
		}
		String checkPwd = MD5Util.sha1(pwStr);
		if(StringUtils.equals(user.getPassword(), checkPwd)){
			LoginUtil.setCurrentUser(user);
		}else{
			errors.rejectValue("loginPswd","wrong_password",errorTip);
			return;
		}
	}
	@RequestMapping(value="/logout")
	public String logout(String backUrl,Model model,HttpServletRequest request,HttpServletResponse response) throws Exception{
		String value = CookieWrapper.getCookieValue(request, YQH_UT);
		String p2pDomainName = p2pDomianName();
		CookieWrapper.clearCookie(response, YQH_UT, p2pDomainName);
		if(value!=null&&loginCache.exists(value)){
			loginCache.delete(value);
		}
		LoginForm loginForm = new LoginForm();
		model.addAttribute("loginForm", loginForm);
		return "login/login";
	}
}
